package com.chinamsp.dydb.query;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import com.chinamsp.dydb.util.BizUtils;

/**
 * 条件  builder 工具类
 * @author shifenghu
 *
 */
public class ConditionBuilder {

	/**
	 * 本次创建的条件
	 */
	private List<Condition> conditions;
	
	
	public ConditionBuilder(){
		conditions = new ArrayList<>();
	}
	
	public ConditionBuilder(int size) {
		conditions = new ArrayList<>(size);
	}
	
	/**
	 * 根据全表达式，增加一个条件，全表达式是包含了：属性_类型_操作类型
	 * @param parameter
	 * @param value
	 * @return
	 */
	public ConditionBuilder addFull(String parameter, Object value) {
		Assert.notNull(parameter, "condition参数不能为空");
		conditions.add(Condition.parseCondition(parameter, value));
		return this;
	}
	
	/**
	 * 根据复杂条件增加
	 * @param propertyName
	 * @param type
	 * @param expression
	 * @param value
	 * @return
	 */
	public ConditionBuilder add(String propertyName, FieldType type, SymbolType expression, Object value){
		Assert.notNull(propertyName, "condition 条件 属性名称不能为空");
		Assert.notNull(type, String.format("[%s] 字段的 condition 条件操作类型不能为空", propertyName));
		Assert.notNull(expression, String.format("[%s][%s] 字段的 condition 条件操作类型不能为空", propertyName, type));
		Assert.isTrue(type.contains(expression), String.format("[%s][%s] 字段 不支持[%s]类型表达式", propertyName, type, expression));
		conditions.add(Condition.parseCondition(propertyName + Condition.FIELD_INTERNAL_DELIMETER + type.getType() + Condition.FIELD_INTERNAL_DELIMETER + expression.getType(), value));
		return this;
	}
	
	/**
	 * 添加 string 表达式
	 * @param propertyName
	 * @param expression
	 * @param value
	 * @return
	 */
	public ConditionBuilder add(String propertyName, SymbolType expression, Object value) {
		return add(propertyName, FieldType.STRING, value);
	}
	
	/**
	 * 添加一个 type 类型的 eq 表达式条件
	 * @param propertyName
	 * @param type
	 * @param value
	 * @return
	 */
	public ConditionBuilder add(String propertyName, FieldType type,  Object value) {
		return add(propertyName, type, SymbolType.EQ, value);
	}
	
	/**
	 * 添加一个 string 类型的 eq 表达式条件
	 * @param propertyName
	 * @param value
	 * @return
	 */
	public ConditionBuilder add(String propertyName, Object value) {
		return add(propertyName, FieldType.STRING, SymbolType.EQ, value);
	}
	
	
	/**
	 * 添加一个或多个 condition
	 * @param conditions
	 * @return
	 */
	public ConditionBuilder add(Condition...conditions) {
		if (conditions != null) {
			for (Condition cond : conditions) {
				this.conditions.add(cond);
			}
		}
		return this;
	}
	
	/**
	 * 添加 多个condition
	 * @param conditions
	 * @return
	 */
	public ConditionBuilder add(List<Condition> conditions) {
		if (!CollectionUtils.isEmpty(conditions)) {
			this.conditions.addAll(conditions);
		}
		return this;
	}
	
	/**
	 * 通过 map<parameter expression, value> 添加 多个条件
	 * @param conditions
	 * @return
	 */
	public ConditionBuilder add(Map<String, Object> conditions) {
		if (!CollectionUtils.isEmpty(conditions)) {
			conditions.forEach((p, v) -> {
				this.conditions.add(Condition.parseCondition(p, v));
			});
		}
		return this;
	}
	
	/**
	 * 根据 全表达式创建单个条件
	 * @param paramter
	 * @param value
	 * @return
	 */
	public static Condition buildFull(String parameter, Object value) {
		return newDefault().addFull(parameter, value).build();
	}
	
	/**
	 * build 一个条件
	 * @param propertyName
	 * @param fieldType
	 * @param symbol
	 * @param value
	 * @return
	 */
	public static Condition build(String propertyName, FieldType fieldType, SymbolType symbol, Object value) {
		return newDefault().add(propertyName, fieldType, symbol, value).build();
	}
	
	/**
	 * build 一个 EQ 条件
	 * @param propertyName
	 * @param fieldType
	 * @param value
	 * @return
	 */
	public static Condition build(String propertyName, FieldType fieldType, Object value) {
		return newDefault().add(propertyName, fieldType, value).build();
	}
	
	/**
	 * build 一个 String.EQ 条件
	 * @param propertyName
	 * @param value
	 * @return
	 */
	public static Condition build(String propertyName, Object value) {
		return newDefault().add(propertyName, value).build();
	}
	
	/**
	 * 生成一个条件
	 * @return
	 */
	public Condition build() {
		return BizUtils.forceOne(conditions);
	}
	
	/**
	 * 生成多个条件
	 * @return
	 */
	public List<Condition> builds(){
		return conditions;
	}
	
	/**
	 * 初始化一个默认数量的 condition builder
	 * @return
	 */
	public static ConditionBuilder newDefault() {
		return new ConditionBuilder();
	}
	
}
